package edu.hit.crawler.io;

import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;

import org.apache.hadoop.io.Writable;

public class FetchOutput implements Writable {

	/** Content was retrieved without errors. */
	public static final int SUCCESS = 1;
	/** Content was not retrieved. Any further errors may be indicated in args. */
	public static final int FAILED = 2;
	/** This protocol was not found. Application may attempt to retry later. */
	public static final int PROTO_NOT_FOUND = 10;
	/** Resource is gone. */
	public static final int GONE = 11;
	/** Resource has moved permanently. New url should be found in args. */
	public static final int MOVED = 12;
	/** Resource has moved temporarily. New url should be found in args. */
	public static final int TEMP_MOVED = 13;
	/** Resource was not found. */
	public static final int NOTFOUND = 14;
	/** Temporary failure. Application may retry immediately. */
	public static final int RETRY = 15;
	/**
	 * Unspecified exception occured. Further information may be provided in
	 * args.
	 */
	public static final int EXCEPTION = 16;
	/** Access denied - authorization required, but missing/incorrect. */
	public static final int ACCESS_DENIED = 17;
	/** Access denied by robots.txt rules. */
	public static final int ROBOTS_DENIED = 18;
	/** Too many redirects. */
	public static final int REDIR_EXCEEDED = 19;
	/** Not fetching. */
	public static final int NOTFETCHING = 20;
	/** Unchanged since the last fetch. */
	public static final int NOTMODIFIED = 21;
	/**
	 * Request was refused by protocol plugins, because it would block. The
	 * expected number of milliseconds to wait before retry may be provided in
	 * args.
	 */
	public static final int WOULDBLOCK = 22;
	/** Thread was blocked http.max.delays times during fetching. */
	public static final int BLOCKED = 23;

	private String url;
	private int statuCode;
	private long lastModifyTime;
	private byte[] content;

	public FetchOutput() {
		url = "";
		statuCode = FAILED;
		setLastModifyTime(0);
		content = new byte[0];
	}

	public FetchOutput(String url, int statuCode) {
		this.url = url;
		this.statuCode = statuCode;
		setLastModifyTime(0);
		content = new byte[0];
	}

	public FetchOutput(String url, long lastModify, byte[] content) {
		if (null == url)
			throw new IllegalArgumentException("null url");
		if (null == content)
			throw new IllegalArgumentException("null content");
		this.url = url;
		this.statuCode = SUCCESS;
		this.lastModifyTime = lastModify;
		this.content = content;
	}

	public FetchOutput(String url, int statuCode, byte[] content) {
		if (null == url)
			throw new IllegalArgumentException("null url");
		if (statuCode <= 0 || statuCode > 600)
			throw new IllegalArgumentException("null statuCode");
		if (null == content)
			throw new IllegalArgumentException("null content");
		this.url = url;
		this.statuCode = statuCode;
		setLastModifyTime(0);
		this.content = content;
	}

	public String getUrl() {
		return url;
	}

	public void setUrl(String url) {
		this.url = url;
	}

	public byte[] getContent() {
		return content;
	}

	public void setContent(byte[] content) {
		this.content = content;
	}

	public int getCode() {
		return statuCode;
	}

	public void setCode(int code) {
		this.statuCode = code;
	}

	public long getLastModifyTime() {
		return lastModifyTime;
	}

	public void setLastModifyTime(long lastModifyTime) {
		this.lastModifyTime = lastModifyTime;
	}

	@Override
	public void readFields(DataInput in) throws IOException {
		url = in.readUTF();
		statuCode = in.readInt();
		lastModifyTime = in.readLong();
		int len = in.readInt();
		content = new byte[len];
		in.readFully(content, 0, len);
	}

	@Override
	public void write(DataOutput out) throws IOException {
		out.writeUTF(url);
		out.writeInt(statuCode);
		out.writeLong(lastModifyTime);
		int len = content.length;
		out.writeInt(len);
		out.write(content);
	}

}
